/*
 * @(#)LogUtil.java	1.1 Sept 30, 2008
 *
 *	The MIT License
 *
 *	Copyright (c) 2008 Malachi de AElfweald <malachid@gmail.com>
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *	THE SOFTWARE.
 */
package org.eoti.util.log;

import org.eoti.util.RuntimeUtil;

import java.util.logging.*;

public enum LogUtil
{
    INSTANCE;
    LogUtil()
    {

    }

	/* @TODO: add Syslog functionality
	 */

	protected String filespec;
	protected int limit;
	protected int count;
	protected Handler handler;
	protected Logger log;

	/**
     * @param filespec Where to place the logs, ie: logs/pandora-log.%g.xml
     * @param limit Bytes per file, ie: 32768 for 32k
     * @param count Number of files for rotation, ie: 10
     * @param level Level to init with, ie: LogLevel.Finest
     * @param initMsg Message to initially start the logs with, ie: "Starting Pandora..."
     */
	public static void init(String filespec, int limit, int count, LogLevel level, String initMsg)
	throws Exception
	{
        INSTANCE.initialize(filespec, limit, count, level, initMsg);
    }

	protected void initialize(String filespec, int limit, int count, LogLevel level, String initMsg)
	throws Exception
	{
		this.filespec = filespec;
		this.limit = limit;
		this.count = count;
		this.handler = new FileHandler(filespec, limit, count);
		this.log = Logger.getLogger("");
		log.addHandler(handler);
		log.setLevel(level.getLevel());
		log.info(initMsg);
	}

	public static Logger getLogger(){return INSTANCE.log;}
	public static Handler getHandler(){return INSTANCE.handler;}

	public static void throwing(String message, Throwable error){log(LogLevel.All, message, error);}

	public static void log(String message){log(LogLevel.All, message, null);}
	public static void log(String message, Throwable error){log(LogLevel.All, message, error);}

	public static void config(String message){log(LogLevel.Config, message, null);}
	public static void config(String message, Throwable error){log(LogLevel.Config, message, error);}

	public static void info(String message){log(LogLevel.Info, message, null);}
	public static void info(String message, Throwable error){log(LogLevel.Info, message, error);}

	public static void fine(String message){log(LogLevel.Fine, message, null);}
	public static void fine(String message, Throwable error){log(LogLevel.Fine, message, error);}

	public static void finer(String message){log(LogLevel.Finer, message, null);}
	public static void finer(String message, Throwable error){log(LogLevel.Finer, message, error);}

	public static void finest(String message){log(LogLevel.Finest, message, null);}
	public static void finest(String message, Throwable error){log(LogLevel.Finest, message, error);}

	public static void severe(String message){log(LogLevel.Severe, message, null);}
	public static void severe(String message, Throwable error){log(LogLevel.Severe, message, error);}

	public static void warning(String message){log(LogLevel.Warning, message, null);}
	public static void warning(String message, Throwable error){log(LogLevel.Warning, message, error);}

	protected static void log(LogLevel level, String message, Throwable error)
	{
		if(INSTANCE.log == null)
		{
//			System.err.format("Attempt to log message before LogUtil was init'd: %s\n", message);
			return;
		}

		// whoCalledMe(depthAboveMe)...
		// depth = 0 = who called me (ie: LogUtil public method)
		// depth = 1 = who called the LogUtil public method
		StackTraceElement caller = RuntimeUtil.whoCalledMe(1);

		if(error == null)
			INSTANCE.log.logp(level.getLevel(), caller.getClassName(), caller.getMethodName(), message);
		else
			INSTANCE.log.logp(level.getLevel(), caller.getClassName(), caller.getMethodName(), message, error);
	}
}